﻿using Zo.Models;
using Logics.Sys;
using Models.Sys;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using Zo.Config;
using Zo.Http;

namespace BSAppDOne.WebAdmin.Custom
{
    /// <summary>
    /// 管理员权限过滤器
    /// </summary>
    
    public class AdminActionFilter : ActionFilterAttribute
    {
        /// <summary>
        /// 忽略权限，也无须登录
        /// </summary>
        public bool NoLogin { get; set; } = false;
        /// <summary>
        /// 需要登录，但是不验证权限
        /// </summary>
        public bool NoCheckRight { get; set; } = false;
        /// <summary>
        /// 每次请求Action之前发生，，在行为方法执行前执行
        /// </summary>
        /// <param name="filterContext"></param>
        public override void OnActionExecuting(ActionExecutingContext filterContext)
        {
            //获取控制器名
            string ControllerName = filterContext.ActionDescriptor.ControllerDescriptor.ControllerName;
            //获取方法名
            string ActionName = filterContext.ActionDescriptor.ActionName;
            //域信息
            string AreaName = filterContext.RouteData.DataTokens["area"].ToString();

            var Controller = filterContext.Controller as Areas.Admin.Controllers.BaseController;

            var token = HttpCookieHelper.GetCookie("Authorization");
            if (!NoLogin)
            {
                if (string.IsNullOrWhiteSpace(token))
                {
                    if (filterContext.HttpContext.Request.IsAjaxRequest())
                    {
                        filterContext.Result = Controller.Success(new ErrorModel(AppConfig.LoginPageUrl, ErrorMsgStatus.LoginTimeOut));
                        return;
                    }
                    else
                    {
                        var Alert = $@"<script type='text/javascript'>
                                        alert('登录超时！系统将退出重新登录！');
                                        top.window.location='{AppConfig.LoginPageUrl}';
                                    </script>";
                        filterContext.Result = new ContentResult() { Content = Alert, ContentType = "text/html;charset=utf-8;" };
                        return;
                    }
                }
                else
                {
                    Controller._Account = new AccountLogic().Get();
                }
            }
          

            if (!NoLogin)
            {
                //1取到所有角色下的权限菜单
                OperationLogic opLogic = new OperationLogic();
                RoleLogic roLogic = new RoleLogic();

                var opList = new List<Sys_Operation>();
                if (Controller._Account.IsSuperAdmin)
                {
                    opList = opLogic.GetOperationList();
                }
                else
                {
                    //获取所有角色的权限字符串
                    string opl = roLogic.GetOperationListById(Controller._Account.RoleIdList);
                    if (!string.IsNullOrEmpty(opl))
                    {
                        opList = opLogic.GetOperationList("Where Id in(" + opl + ")");
                    }
                    else
                    {
                        throw new ErrorBox("Sorry, you have no right!");
                    }
                }
                //获取显示的菜单项
                List<Sys_Operation> menus = opList.Where(c => c.ParentId == 0 && c.IsMenu == (int)Sys_Operation.IsMenuState.yes).ToList();
                foreach (var menu in menus)
                {
                    var chi = opList.Where(c => c.ParentId == menu.Id && c.IsMenu == (int)Sys_Operation.IsMenuState.yes).ToList();
                    foreach (var c in chi)
                    {
                        c.Url = "/" + c.Right.Replace("Areas@", "/").Replace("Controller@", "/");
                    }
                    if (menu.IsTopClickMenu == (int)Sys_Operation.IsTop.yes)
                    {
                        menu.Url = "/" + menu.Right.Replace("Areas@", "/").Replace("Controller@", "/");
                    }
                    menu.Child = new List<Sys_Operation>();
                    menu.Child.AddRange(chi);
                }

                //根据当前操作的域和方法去匹配父级菜单
                var opActive = opList.Where(c => c.Right.Contains(AreaName + "Areas@" + ControllerName + "Controller@") && c.IsMenu == (int)Sys_Operation.IsMenuState.yes).FirstOrDefault();
                if (opActive != null && opActive.Id != 1)
                {
                    var opActive2 = opList.Where(c => c.Id == opActive.ParentId).SingleOrDefault();
                    Controller.ViewBag.activeMenuCid = opActive.Id;
                    var pid = opActive.Id;
                    if (opActive2 != null)
                    {
                        pid = opActive2.Id;
                    }
                    Controller.ViewBag.activeMenuPid = pid;

                }
                //首页
                if (opActive != null && opActive.Id == 1)
                {
                    Controller.ViewBag.activeMenuPid = opActive.Id;
                }
                Controller.ViewBag.menus = menus.OrderByDescending(c => c.Sort).ToList();
                Controller.ViewBag.user = Controller._Account;


                //验证权限
                IEnumerable<string> right = new List<string>();
                foreach (var item in opList)
                {
                    right = right.Concat(item.Right.Split(','));
                }
                var method = AreaName + "Areas@" + ControllerName + "Controller@" + ActionName;

                if (!right.Any(c => c.ToUpper().Equals(method.ToUpper())) && !this.NoCheckRight)
                {
                    //没有权限，如果是超级管理员这里就不用了!!
                    throw new ErrorBox("Sorry, you have no right!");
                }

                //此处加入管理员操作日志

            }
        }
    }
}